package us.wili.dev.netty.model.game;

import com.google.gson.annotations.Expose;
import us.wili.dev.common.model.BaseModelWithId;
import us.wili.dev.netty.model.GameLog;
import us.wili.dev.netty.model.PlayerOpt;
import us.wili.dev.netty.util.CardGroup;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;

public class Room extends BaseModelWithId {
    /**
     * 游戏日志
     */
    protected GameLog gameLog;

    /**
     * 玩家操作
     */
    protected List<PlayerOpt> opts;

    /**
     * 游戏类型
     */
    private Integer type;

    /**
     * 允许带入的最大筹码
     */
    private int maxChips;
    /**
     * 允许带入的最小筹码
     */
    private int minChips;
    /**
     * 大盲下注筹码
     */
    @Expose
    private int bigBet;
    /**
     * 小盲下注筹码
     */
    @Expose
    private int smallBet;
    /**
     * 最大玩家数
     */
    @Expose
    private int maxPlayers;
    /**
     * 最小玩家数
     */
    @Expose
    private int minPlayers;
    /**
     * D，最佳座位，庄家（座位号）
     */
    @Expose
    private int dealer;
    /**
     * 小盲玩家座位号
     */
    @Expose
    private int smallBetSeatNum;
    /**
     * 大盲玩家座位号
     */
    @Expose
    private int bigBetSeatNum;
    /**
     * 游戏状态（0，等待；1，游戏，2结算中）
     */
    @Expose
    private AtomicInteger gamestate = new AtomicInteger(0);
    /**
     * 房间状态（0，不可加入；1，可加入）
     */
    private int roomstate = 1;
    /**
     * 房间中处于等待状态的玩家列表
     */
    @Expose
    private List<Player> waitPlayers = new CopyOnWriteArrayList<Player>();
    /**
     * 房间中处于游戏状态的玩家列表
     */
    @Expose
    protected List<Player> ingamePlayers = new CopyOnWriteArrayList<Player>();
    /**
     * 一局的牌组
     */
    protected ArrayList<Integer> cardList = CardGroup.getRandomCards();
    /**
     * 公共牌
     */
    @Expose
    protected List<Integer> communityCards = new ArrayList<Integer>();
    /**
     * 奖池,下注总额
     */
    @Expose
    protected long betAmount;
    /**
     * 每个玩家下的注，玩家和其本局游戏下注的总额
     */
    protected Map<Integer, Long> betMap = new LinkedHashMap<>();

    /**
     * 在一回合中，每个玩家下的注[座位号，本轮下注额]
     */
    @Expose
    protected Map<Integer, Long> betRoundMap = new LinkedHashMap<>();

    /**
     * 操作过的玩家列表
     */
    public List<Integer> donePlayerList = new ArrayList<Integer>();

    /**
     * 下一个行动的玩家id
     */
    @Expose
    protected int nextturn = 0;// next player
    /**
     * 每轮第一个行动的玩家
     */
    protected int roundturn = 0;
    /**
     * 本轮游戏玩家下的最大注倍数，第一轮为1，一共3种，1,2,4
     */
    protected int roundMaxBet = 1;
    /**
     * 存放座位号的栈(空闲座位)
     */
    @Expose
    private Stack<Integer> freeSeatStack;
    /**
     * 两局之间的间隔时间
     */
    @Expose
    private int restBetweenGame = 5000;

    /**
     * 操作超时时间，单位毫秒（玩家在规定时间内没有完成操作，则系统自动帮其弃牌）
     */
    @Expose
    private int optTimeout = 10000;

    /**
     * 房间中等待操作的计时器(一个房间中不允许同时生成多个计时器)
     */
    private Timer timer = new Timer();
    /**
     * 游戏中玩家成手牌列表
     */
    @Expose
    protected Map<Integer, List<Integer>> finalCardsMap = new HashMap<Integer, List<Integer>>();
    /**
     * 最后亮牌玩家手牌列表
     */
    @Expose
    protected Map<Integer, List<Integer>> handCardsMap = new HashMap<Integer, List<Integer>>();
    /**
     * 所有获胜玩家列表
     */
    @Expose
    protected Map<Integer, Long> winPlayersMap = new HashMap<Integer, Long>();

    /**
     * 邀请码
     */
    private String shareCode;

    /**
     * 房主ID
     */
    private Long ownerID;

    /**
     * 房间计时器
     */
    private TimerTask tt;

    public Long getOwnerID() {
        return ownerID;
    }

    public void setOwnerID(Long ownerID) {
        this.ownerID = ownerID;
    }

    public String getShareCode() {
        return shareCode;
    }

    public void setShareCode(String shareCode) {
        this.shareCode = shareCode;
    }

    public GameLog getGameLog() {
        return gameLog;
    }

    public void setGameLog(GameLog gameLog) {
        this.gameLog = gameLog;
    }

    public List<PlayerOpt> getOpts() {
        return opts;
    }

    public void setOpts(List<PlayerOpt> opts) {
        this.opts = opts;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public int getMaxChips() {
        return maxChips;
    }

    public void setMaxChips(int maxChips) {
        this.maxChips = maxChips;
    }

    public int getMinChips() {
        return minChips;
    }

    public void setMinChips(int minChips) {
        this.minChips = minChips;
    }

    public int getBigBet() {
        return bigBet;
    }

    public void setBigBet(int bigBet) {
        this.bigBet = bigBet;
    }

    public int getSmallBet() {
        return smallBet;
    }

    public void setSmallBet(int smallBet) {
        this.smallBet = smallBet;
    }

    public int getMaxPlayers() {
        return maxPlayers;
    }

    public void setMaxPlayers(int maxPlayers) {
        this.maxPlayers = maxPlayers;
    }

    public int getMinPlayers() {
        return minPlayers;
    }

    public void setMinPlayers(int minPlayers) {
        this.minPlayers = minPlayers;
    }

    public int getDealer() {
        return dealer;
    }

    public void setDealer(int dealer) {
        this.dealer = dealer;
    }

    public int getSmallBetSeatNum() {
        return smallBetSeatNum;
    }

    public void setSmallBetSeatNum(int smallBetSeatNum) {
        this.smallBetSeatNum = smallBetSeatNum;
    }

    public int getBigBetSeatNum() {
        return bigBetSeatNum;
    }

    public void setBigBetSeatNum(int bigBetSeatNum) {
        this.bigBetSeatNum = bigBetSeatNum;
    }

    public AtomicInteger getGamestate() {
        return gamestate;
    }

    public void setGamestate(AtomicInteger gamestate) {
        this.gamestate = gamestate;
    }

    public int getRoomstate() {
        return roomstate;
    }

    public void setRoomstate(int roomstate) {
        this.roomstate = roomstate;
    }

    public List<Player> getWaitPlayers() {
        return waitPlayers;
    }

    public void setWaitPlayers(List<Player> waitPlayers) {
        this.waitPlayers = waitPlayers;
    }

    public List<Player> getIngamePlayers() {
        return ingamePlayers;
    }

    public void setIngamePlayers(List<Player> ingamePlayers) {
        this.ingamePlayers = ingamePlayers;
    }

    public ArrayList<Integer> getCardList() {
        return cardList;
    }

    public void setCardList(ArrayList<Integer> cardList) {
        this.cardList = cardList;
    }

    public List<Integer> getCommunityCards() {
        return communityCards;
    }

    public void setCommunityCards(List<Integer> communityCards) {
        this.communityCards = communityCards;
    }

    public long getBetAmount() {
        return betAmount;
    }

    public void setBetAmount(long betAmount) {
        this.betAmount = betAmount;
    }

    public Map<Integer, Long> getBetMap() {
        return betMap;
    }

    public void setBetMap(Map<Integer, Long> betMap) {
        this.betMap = betMap;
    }

    public Map<Integer, Long> getBetRoundMap() {
        return betRoundMap;
    }

    public void setBetRoundMap(Map<Integer, Long> betRoundMap) {
        this.betRoundMap = betRoundMap;
    }

    public List<Integer> getDonePlayerList() {
        return donePlayerList;
    }

    public void setDonePlayerList(List<Integer> donePlayerList) {
        this.donePlayerList = donePlayerList;
    }

    public int getNextturn() {
        return nextturn;
    }

    public void setNextturn(int nextturn) {
        this.nextturn = nextturn;
    }

    public int getRoundturn() {
        return roundturn;
    }

    public void setRoundturn(int roundturn) {
        this.roundturn = roundturn;
    }

    public int getRoundMaxBet() {
        return roundMaxBet;
    }

    public void setRoundMaxBet(int roundMaxBet) {
        this.roundMaxBet = roundMaxBet;
    }

    public Stack<Integer> getFreeSeatStack() {
        return freeSeatStack;
    }

    public void setFreeSeatStack(Stack<Integer> freeSeatStack) {
        this.freeSeatStack = freeSeatStack;
    }

    public int getRestBetweenGame() {
        return restBetweenGame;
    }

    public void setRestBetweenGame(int restBetweenGame) {
        this.restBetweenGame = restBetweenGame;
    }

    public int getOptTimeout() {
        return optTimeout;
    }

    public void setOptTimeout(int optTimeout) {
        this.optTimeout = optTimeout;
    }

    public Timer getTimer() {
        return timer;
    }

    public void setTimer(Timer timer) {
        this.timer = timer;
    }

    public Map<Integer, List<Integer>> getFinalCardsMap() {
        return finalCardsMap;
    }

    public void setFinalCardsMap(Map<Integer, List<Integer>> finalCardsMap) {
        this.finalCardsMap = finalCardsMap;
    }

    public Map<Integer, List<Integer>> getHandCardsMap() {
        return handCardsMap;
    }

    public void setHandCardsMap(Map<Integer, List<Integer>> handCardsMap) {
        this.handCardsMap = handCardsMap;
    }

    public Map<Integer, Long> getWinPlayersMap() {
        return winPlayersMap;
    }

    public void setWinPlayersMap(Map<Integer, Long> winPlayersMap) {
        this.winPlayersMap = winPlayersMap;
    }

    public TimerTask getTt() {
        return tt;
    }

    public void setTt(TimerTask tt) {
        this.tt = tt;
    }
}
